package com.warm.common.word;

import com.alibaba.fastjson.JSONObject;

import java.io.File;
import java.util.*;

/**
 * @Description Word
 * @Author iyb-liangchuang
 * @Date 2021/5/28 10:19
 */
public class Word {
    private final String IMAGE_POSTFIX = ".png";
    private final String RID_PREFIX = "rId00";

    private JSONObject data; // 基础数据源
    private String templatePath; // 模板路径

    private Config config;

    private List<Image> imageList; // rels 配置中循环图片配置
    /** word 内容填充 获取图片的id, 图片名称是key 图片id是value */
    private Map<String, Object> imageMap; // document.xml 取图片名 和 rId

    public Word(JSONObject data, String templatePath) {
        this.data = data;
        this.templatePath = templatePath;
        init();
    }

    private void init(){
        File fileDir = new File(templatePath);
        File[] templateFiles = fileDir.listFiles();
        if(templateFiles == null || templateFiles.length == 0) {
            System.out.println("模板文件为空");
            return;
        }

        this.imageList = new ArrayList<>();
        this.imageMap = new HashMap<>();
        initFile(templateFiles);

        // 自定义的图片文件：数据格式 {name, data, type}
        JSONObject dynamicImages = data.getJSONObject("dynamicImages");
        if(dynamicImages != null && !dynamicImages.isEmpty()){
            handleImage(dynamicImages);
        }
    }

    private void initFile(File[] templateFiles) {
        Config config = new Config();
        Image image = null;
        File file = null;
        int j = 0;
        for(int i = 0; i < templateFiles.length; i++){
            file = templateFiles[i];
            if(file.getName().endsWith(".docx")){
                config.setTemplateFilePath(file.getPath());
                continue;
            } else if(file.getName().endsWith(".xml")){
                config.setDocumentFileName(file.getName());
                continue;
            } else if(file.getName().endsWith(".rels")){
                config.setDocumentRelsFileName(file.getName());
                continue;
            } else if(file.getName().endsWith(".png") || file.getName().endsWith(".jpg") || file.getName().endsWith(".jpeg")) { // 图片文件
                image = new Image();
                image.setId(RID_PREFIX + j);
                image.setName(file.getName().substring(0, file.getName().lastIndexOf(".")));
                image.setFilename(file.getName());
                image.setData(file.getPath());
                image.setType(ImageType.FILE.getType());
                imageList.add(image);
                imageMap.put(image.getName(), image.getId());
                j += 1;// 保证生成的 RId 唯一、连续
            }
        }
        this.config = config;
    }

    private void handleImage(JSONObject handleImgList){
        Image img = null;
        String key = null;
        for(Map.Entry entry : handleImgList.entrySet()){
            key = (String) entry.getKey();
            JSONObject value = (JSONObject) entry.getValue();

            if(value.get("data") instanceof List){ // data 里面包含多个, 目前集合类型只支持 url, base64
                List datas = (List) value.get("data");
                List<String> rids = new ArrayList<>();
                for (int j = 0; j < datas.size(); j++){
                    img = new Image();
                    img.setId(RID_PREFIX + (imageList.size() + 1));
                    img.setType(value.getString("type"));
                    img.setData(datas.get(j));
                    img.setName(img.getId());
                    img.setFilename(img.getName() + IMAGE_POSTFIX);

                    imageList.add(img);
                    rids.add(img.getId());
                }
                imageMap.put(key, rids);
            } else { // 单个
                // 更新 imageList 里面的数据源
                Optional<Image> first = imageList.stream().filter(image -> entry.getKey().equals(image.getName())).findFirst();
                img = first.isPresent() ? first.get() : new Image();
                img.setData(value.get("data"));
                img.setType(value.getString("type"));
                if(img.getId() != null) return;

                // 原始没有的图片源
                img.setName(key);
                img.setFilename(key + IMAGE_POSTFIX);
                img.setId(RID_PREFIX + (imageList.size() + 1));
                imageList.add(img);
                imageMap.put(img.getName(), img.getId());
            }
        }
    }

    public class Image { // 图片媒体文件
        /** doucment.xml.rels 中的图片id配置 */
        private String id;
        /** 图片名称 */
        private String name;
        /** 后缀 */
        private String filename;
        /** 图片文件路径/流 */
        private Object data;
        /** 类型 file-本地文件  url-图片链接 in-inputStream */
        private String type;

        public String getId() {
            return id;
        }

        public void setId(String id) {
            this.id = id;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getFilename() {
            return filename;
        }

        public void setFilename(String filename) {
            this.filename = filename;
        }

        public Object getData() {
            return data;
        }

        public void setData(Object data) {
            this.data = data;
        }

        public String getType() {
            return type;
        }

        public void setType(String type) {
            this.type = type;
        }
    }

    public class Config {
        private String templateFilePath;
        private String documentFileName;
        private String documentRelsFileName;

        public String getTemplateFilePath() {
            return templateFilePath;
        }

        public String getDocumentFileName() {
            return documentFileName;
        }

        public String getDocumentRelsFileName() {
            return documentRelsFileName;
        }

        public void setTemplateFilePath(String templateFilePath) {
            this.templateFilePath = templateFilePath;
        }

        public void setDocumentFileName(String documentFileName) {
            this.documentFileName = documentFileName;
        }

        public void setDocumentRelsFileName(String documentRelsFileName) {
            this.documentRelsFileName = documentRelsFileName;
        }
    }

    public enum ImageType{
        URL("url"),
        FILE("file"),
        STREAM("stream"),
        BASE64("base64"),
        QRCODE("qrcode");

        private String type;
        ImageType(String type){
            this.type = type;
        }

        public String getType(){
            return type;
        }
    }

    public JSONObject getData() {
        return data;
    }

    public void setData(JSONObject data) {
        this.data = data;
    }

    public String getTemplatePath() {
        return templatePath;
    }

    public void setTemplatePath(String templatePath) {
        this.templatePath = templatePath;
    }

    public Config getConfig() {
        return config;
    }

    public void setConfig(Config config) {
        this.config = config;
    }

    public List<Image> getImageList() {
        return imageList;
    }

    public void setImageList(List<Image> imageList) {
        this.imageList = imageList;
    }

    public Map<String, Object> getImageMap() {
        return imageMap;
    }

    public void setImageMap(Map<String, Object> imageMap) {
        this.imageMap = imageMap;
    }
}
